package com.gopay.checkorder.service.task;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.dao.BcdlQueryBalanceDAO;
import com.gopay.checkorder.service.BcdlOrderSendBankService;
import com.gopay.common.cipher.utils.LoggerMaskUtils;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BcdlQueryBalance;
import com.gopay.common.domain.bank.BcdlResult;
import com.gopay.common.exception.GopayException;
import com.gopay.common.order.dao.CommonQueryDAO;
import com.gopay.common.util.DateUtils;
import com.gopay.common.util.StringTools;
import com.gopay.common.util.spring.SpringContextUtil;
import com.gopay.sms.client.GopaySMSHttpClient;
import com.gopay.sms.common.constants.SMSAppId;
import com.gopay.sms.common.domain.RequestVO;
import com.gopay.sms.common.domain.ResponseVO;

/**
 * 余额查询定时任务
 *
 * @author lynn
 * @data
 */
public class BcdlOrderCheckBalanceTaskImpl implements Task {
	private final static Logger logger = LoggerFactory.getLogger(BcdlOrderCheckBalanceTaskImpl.class);

	@Resource(name = "bcdlQueryBalanceDAO")
	private BcdlQueryBalanceDAO bcdlQueryBalanceDAO;

	@Resource(name = "commonQueryDAO")
	private CommonQueryDAO commonQueryDAO;

	private static final String SWITCH_ON = "on";

	private int warnCount = 0;

	@Resource(name = "smsConfig")
	private Map<String, String> smsConfig;

	private String bank;
	private String notifyCpsUrl;

	@Override
	public void doTask() {
		logger.info("银企直连余额查询job--开始，bank=" + bank);
		process(bank);
		logger.info("银企直连余额查询job--结束，bank=" + bank);
	}

	public void process(String bank) {

		try {

			String beanName = getSendBankBeanName(bank);

			if (false == SpringContextUtil.containsBean(beanName)) {
				logger.info("spring bean does not exist: " + beanName);
				return;
			}

			long currentTime = System.currentTimeMillis();
			String queryId = "QU" + String.valueOf(currentTime);

			BcdlOrderSendBankService sendBankService = (BcdlOrderSendBankService) SpringContextUtil.getBean(beanName);

			
			BcdlQueryBalance bcdlQuery = new BcdlQueryBalance();
			
			// 查询账户余额
			List<BcdlQueryBalance> bcdlQuerys = getBcdlQueryOrder(bank);
			if (bcdlQuerys != null && bcdlQuerys.size() > 0) {
				bcdlQuery = bcdlQuerys.get(0);
			}else{
				bcdlQuery.setQueryOrderId(queryId);
				bcdlQuery.setQueryBankCode(bank);
			}

			logger.error("工行银企直连 查询余额--开始 ，orderId=" + bcdlQuery.getQueryOrderId() + ",bank=" + bank);
			BcdlResult result = sendBankService.queryBalance(bcdlQuery);
			logger.error("工行银企直连 查询余额--结束 ，orderId=" + bcdlQuery.getQueryOrderId() + ",ResultCode=" + result.getResultCode() + ",isSuccess=" + result.isSuccess());

			if (result != null && result.isSuccess()) {
				String balance = result.getModel("balance").toString();
				logger.error("工行银企直连 当前余额：" + balance);
				BigDecimal dBalance = new BigDecimal(balance);

				List<Object[]> limitConfigs = getLimitConfig(bank);
				String warnAmt = "";
				String mobileNos = "";
				for (Object[] limitConfig : limitConfigs) {
					warnAmt = StringTools.checkNulltoString(limitConfig[0]);
					mobileNos = StringTools.checkNulltoString(limitConfig[1]);
				}
				BigDecimal bWarnAmt = new BigDecimal(warnAmt);
				if (bWarnAmt.compareTo(dBalance) > 0) {
					if (warnCount < 3) {
						sendSms(mobileNos, balance);
						warnCount++;
					}
				} else {
					warnCount = 0;
				}

				if (result != null && result.isSuccess()) {
					notifyCps(bank, result);
				}

			}

		} catch (Exception e) {
			logger.error("checkOrder querybalance error message: ,bank=" + bank, e);
		}
	}

	private void sendSms(String mobileNos, String balance) {
		try {
			String msg = "余额不足，当前余额：" + balance;
			if (SWITCH_ON.equals(smsConfig.get("switch"))) {
				// 自定义短信内容，不提供验证码校验功能
				RequestVO req = new RequestVO();
				req.setAppId(SMSAppId._90000.value);
				req.setMobile(mobileNos);// 电话号码(多个以逗号分隔)
				req.setContent(DateUtils.getCurrDate() + "," + bank + " :" + msg);
				ResponseVO resp = GopaySMSHttpClient.getInstance().createVerificationCode(req);

				if (resp != null) {
					if ("100".equals(resp.getStatusCode())) {
						logger.error("[balance_sms]银行【" + bank + "】余额不足报警短信发送成功");
					} else {
						logger.error("[balance_sms]银行【" + bank + "】余额不足报警短信发送失败，原因：" + resp.getMessage());
					}
				}
			} else {
				logger.error("[balance_sms] 余额不足报警短信发送已关闭，信息: 银行" + bank);

			}
		} catch (Exception e) {
			logger.error("[balance_sms]senSMS error: ", e);
		}

	}

	public List<Object[]> getLimitConfig(String bank) {
		StringBuffer sql = new StringBuffer();
		sql.append("select a.WARNING_AMT,a.MOBlIE_NOS from AS_BANK_LIMIT_CONFIG a ");
		sql.append("where a.BANK_CODE = :bankCode");
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("bankCode", bank);
		List<Object[]> list = commonQueryDAO.findBySql(sql.toString(),params);
		return list;

	}

	public List<BcdlQueryBalance> getBcdlQueryOrder(String bank) {
		return bcdlQueryBalanceDAO.getBcdlQueryByBankCodeAndOrderStatus(bank, BankOrderStatus.ACCEPTED);
	}

	private String getSendBankBeanName(String bankCode) throws GopayException {
		String beanName = bankCode + "-BCDL";
		return beanName;
	}

	private String notifyCps(String bank, BcdlResult result) {
		String notifyUrl = null;
		if (ProcCodeConstants.PROC_CODE_100S1000.equals(result.getResultCode())) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

			StringBuffer paramters = new StringBuffer();
			StringBuffer paramtersLog = new StringBuffer();
			paramters.append(notifyCpsUrl).append("?");
			paramters.append("resultCode=").append(ProcCodeConstants.PROC_CODE_100S1000);
			paramters.append("&bankCode=").append(bank);
			paramters.append("&bankAcctAmt=").append((String) result.getModel("balance"));
			// paramters.append("&bankName=").append(getBankName(bank));
			paramtersLog.append(paramters);
			paramters.append("&bankCardNo=").append((String) result.getModel("payAccNum"));
			paramters.append("&bankAcctLastUpdTs=").append(sdf.format(new Date()));
			paramtersLog.append("&bankCardNo=").append(LoggerMaskUtils.maskString((String) result.getModel("payAccNum")));
			paramtersLog.append("&bankAcctLastUpdTs=").append(sdf.format(new Date()));
			notifyUrl = paramters.toString();
			logger.error("银企直连 查询余额--通知cps开始 ，响应信息：" + paramtersLog);
		} else {
			StringBuffer paramters = new StringBuffer();
			paramters.append(notifyCpsUrl).append("?");
			paramters.append("resultCode=").append(ProcCodeConstants.PROC_CODE_100E6027);
			paramters.append("&bankCode=").append(bank);
			notifyUrl = paramters.toString();
			logger.error("银企直连 查询余额--通知cps开始 ，响应信息：" + notifyUrl);
		}

		StringBuffer sb = new StringBuffer();
		try {
			URL hp = new URL(notifyUrl);
			URLConnection conn = hp.openConnection();
			conn.connect();
			InputStream is = conn.getInputStream();
			java.io.BufferedReader in = new BufferedReader(new InputStreamReader(is, "utf-8"));

			String line = "";
			while ((line = in.readLine()) != null) {
				sb.append(line);
			}
			in.close();
			logger.error("银企直连 查询余额--通知cps结束 ： " + sb.toString());
		} catch (Exception e) {
			logger.error("银企直连 查询余额--通知cps报错: ", e);
			return null;
		}

		return sb.toString();
	}

	public void setBank(String bank) {
		this.bank = bank;
	}

	public void setNotifyCpsUrl(String notifyCpsUrl) {
		this.notifyCpsUrl = notifyCpsUrl;
	}

}
